/*!
 * \file tokens.cpp
 */
#include <stdio.h>
#include "tokens.h"
#include "SymbolTable.h"
#include <vector>
#include <map>
#include <string>
#include <cassert>
#include "utility.h"
#include "cl-ll.h"

int lineNo;

#ifndef DEBUG_FLEX

void separator(const char *p)
{
}


CSymbolTable<int> m_integerConst;

int integerConst(int v)
{
  return m_integerConst.put(v);
}

int integerConst(const char *p)
{
  return integerConst(atoi(p));
}

int getIntegerConst(int attr)
{
  return m_integerConst.get(attr);
}


CSymbolTable<float> m_floatingConst;

int floatingConst(float v)
{
  return m_floatingConst.put(v);
}

int floatingConst(const char *p)
{
  return floatingConst(atof(p));
}

float getFloatingConst(int attr)
{
  return m_floatingConst.get(attr);
}


CSymbolTable<std::string> m_identifiers;

void identifier(const char *p)
{
  yylval=m_identifiers.put(p);
}

const char* getIdentifier(int attr)
{
  static char b[100];
  if(attr<0)
  {
    sprintf(b,"temp%d",-attr);
    return b;
  }
  return m_identifiers.get(attr).c_str();
}

typedef std::map<std::string,int> CStringIdMap;

void oper(const char *p)
{
  static const CPodPair<const char*,int> _op[]=
  {
//AssignOperation "+="|"-="|"*="|"/="|"="
    {"+=",OPERATOR_PLUS_ASSIGN},
    {"-=",OPERATOR_MINUS_ASSIGN},
    {"*=",OPERATOR_MUL_ASSIGN},
    {"/=",OPERATOR_DIV_ASSIGN},
    {"=",OPERATOR_ASSIGN},

//AddOperation [+-]
    {"+",OPERATOR_PLUS},
    {"-",OPERATOR_MINUS},

//MultOperation [*/]
    {"*",OPERATOR_MUL},
    {"/",OPERATOR_DIV},

//RelOperation [<>]|"=="|"!="|"<="|">="
    {"<",OPERATOR_LT},
    {">",OPERATOR_GT},
    {"==",OPERATOR_EQ},
    {"!=",OPERATOR_NE},
    {"<=",OPERATOR_LE},
    {">=",OPERATOR_GE},

//UnaryOperation "++"|"--"
    {"++",OPERATOR_INC},
    {"--",OPERATOR_DEC},
  };
  
  static const CStringIdMap op(_op,_op+COUNT(_op));
  
  CStringIdMap::const_iterator it=op.find(p);
  assert(it!=op.end());
  yylval=it->second;
}

void keyword(const char *p)
{
  static const CPodPair<const char*,int> _op[]=
  {
//TypeBase "int"|"float"|"bool"
    {"int",KEYWORD_INT},
    {"float",KEYWORD_FLOAT},
    {"bool",KEYWORD_BOOL},

//BooleanLiteral "true"|"false"
    {"true",KEYWORD_TRUE},
    {"false",KEYWORD_FALSE},
  };

  static const CStringIdMap op(_op,_op+COUNT(_op));
  
  CStringIdMap::const_iterator it=op.find(p);
  assert(it!=op.end());
  yylval=it->second;
}

#endif

int yyerror(const char *p)
{
  printf("%s: %d\n",p,lineNo);
  return 0;
}
